package com.t13max.game.entity;

import com.google.protobuf.Message;
import com.t13max.game.consts.UnitBits;
import com.t13max.game.pos.Position;
import com.t13max.game.pos.Vector3D;
import com.t13max.game.world.World;
import com.t13max.game.world.chunk.Chunk;
import com.t13max.util.TimeUtil;
import lombok.Getter;

import java.util.BitSet;

/**
 * 实体 顶级父类
 *
 * @author: t13max
 * @since: 15:53 2024/7/25
 */
@Getter
public abstract class Entity implements IEntity {

    protected long id;
    //所在世界
    protected World world;
    //所在位置
    protected Vector3D position;
    //朝向
    protected Vector3D direction;
    //状态
    protected BitSet bitSet = new BitSet(63);

    public Entity() {
    }

    public Entity(long id) {
        this.id = id;
    }

    /**
     * tick!
     *
     * @Author t13max
     * @Date 16:08 2024/7/25
     */
    @Override
    public void pulse() {

    }

    @Override
    public void pulsePerSec() {

    }

    /**
     * 实体进入世界
     *
     * @Author t13max
     * @Date 15:59 2024/12/6
     */
    @Override
    public void enterWorld(World world) {

        if (this.world != null) {
            //错误处理
            return;
        }

        enterWorldBefore();

        this.world = world;
        this.world.enterWorld(this);

        enterWorldAfter();
    }

    /**
     * 实体离开世界
     *
     * @Author t13max
     * @Date 16:00 2024/12/6
     */
    @Override
    public void leaveWorld(World world) {

        if (this.world == null || this.world != world) {
            return;
        }

        leaveWorldBefore();

        this.world.leaveWorld(this);
        this.world = null;

        leaveWorldAfter();
    }

    /**
     * 进入世界前
     *
     * @Author t13max
     * @Date 16:00 2024/12/6
     */
    protected void enterWorldBefore() {

    }

    /**
     * 进入世界后
     *
     * @Author t13max
     * @Date 16:00 2024/12/6
     */
    protected void enterWorldAfter() {

    }

    /**
     * 离开世界前
     *
     * @Author t13max
     * @Date 16:00 2024/12/6
     */
    protected void leaveWorldBefore() {

    }

    /**
     * 离开世界后
     *
     * @Author t13max
     * @Date 16:00 2024/12/6
     */
    protected void leaveWorldAfter() {

    }

    @Override
    public boolean isMovable() {
        return this.bitSet.get(UnitBits.MOVING);
    }

    @Override
    public boolean getBit(int index) {
        return this.bitSet.get(index);
    }

    @Override
    public void setBit(int index, boolean apply) {
        this.bitSet.set(index, apply);
        onBitExChanged(index, apply);
    }

    protected void onBitExChanged(int bit, boolean apply) {

    }

    @Override
    public Position getDataPos() {
        return null;
    }

    /**
     * 位置变化
     *
     * @Author t13max
     * @Date 16:06 2024/12/6
     */
    @Override
    public void changePosition(Vector3D newPos) {
        Vector3D oldPos = this.position;
        this.position = newPos;
        this.world.onObjectMoved(this, oldPos, newPos);
    }

    /**
     * 实体所在区块变化
     * 被区块模块调用
     *
     * @Author t13max
     * @Date 16:03 2024/12/6
     */
    @Override
    public void onChunkChanged(Chunk leaveChunk, Chunk enterChunk) {
        //获取新的格子在原先格子的方向
        int chunkDir = leaveChunk.where(enterChunk);
        //离开原视野单元格
        onChunkLeave(leaveChunk, chunkDir);
        //进入新的视野单元格
        onChunkEnter(enterChunk, chunkDir);
    }

    @Override
    public void moveTowards(IEntity other, double distance) {

    }

    /**
     * 实体进入某区块
     * 同步消息等 区块的实体进入再上一层已经被调用
     *
     * @Author t13max
     * @Date 16:21 2024/12/6
     */
    private void onChunkEnter(Chunk enterChunk, int chunkDir) {

        //同步消息给相关实体
    }

    /**
     * 实体离开某区块
     *
     * @Author t13max
     * @Date 16:21 2024/12/6
     */
    private void onChunkLeave(Chunk leaveChunk, int chunkDir) {

        //同步消息给相关实体
    }

    @Override
    public void changeDirection(Vector3D direction) {
        this.direction = direction;
    }

    @Override
    public Vector3D getDirection() {
        return direction;
    }

    @Override
    public float getModelRadius() {
        return 1;
    }

    @Override
    public void changeSpeed(float selfSpeed, float targetSpeed) {

    }

    @Override
    public float getSpeed() {
        return 1;
    }

    @Override
    public long getTime() {
        if (world == null) {
            return TimeUtil.nowMills();
        }
        return this.world.getTime();
    }

    public final void sendMsgToView(Message message, long exceptId) {

    }


    @Override
    public void onDeath(IEntity caster) {

    }

    @Override
    public void onRevive() {

    }

    @Override
    public void sendMsg(Message message) {

    }

    @Override
    public boolean isInWorld() {
        return false;
    }

    @Override
    public void setHp(float curr) {

    }

    @Override
    public void serializeRoleInfo() {

    }

    @Override
    public IndirectObject<IEntity> getIndirectObject() {
        return null;
    }

    @Override
    public int distance(Vector3D position) {
        return 0;
    }

    @Override
    public boolean isVisibleToOthers(IEntity other) {
        return false;
    }

    @Override
    public Vector3D getNormalizeDir() {
        return null;
    }

    @Override
    public void killMySelf() {

    }

}
